package JUC.printWhen5;


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @className: PhaserList
 * @Description:
 * @Author: wangyifei
 * @Date: 2022/9/5 17:02
 */
public class PhaserList {
    private List<Integer> list = new ArrayList<>();
    public void add(Integer i){
        list.add(i);
    }
    public int size(){
        return list.size();
    }
    public static void main(String[] args) {
        PhaserList list = new PhaserList();
        PrintPhase phase = new PrintPhase();
        phase.bulkRegister(2);
        Abs t1 = new Thread1(phase , list);
        Abs t2 = new Thread2(phase , list);
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2 , 2
                ,1000
                , TimeUnit.SECONDS
                , new ArrayBlockingQueue<>(1000));
        pool.execute(t1);
        pool.execute(t2);
        pool.shutdown();
    }
    public static class Thread2 extends Abs {

        public Thread2(Phaser phaser, PhaserList list) {
            super(phaser, list);
        }

        @Override
        public void run() {
            // 直接进入二个阶段
            phaser.arriveAndAwaitAdvance();
            System.out.println("list size is " + list.size());
            phaser.arriveAndAwaitAdvance();
        }
    }
    public static class Thread1 extends Abs {

        public Thread1(Phaser phaser , PhaserList list) {
            super(phaser , list);
        }

        @Override
        public void run() {
            for(int i = 0 ; i < 10 ; i++){
                list.add(i);
                System.out.println("add " + i);
                if(list.size() == 4){
                    // 进入第二阶段
                    phaser.arriveAndAwaitAdvance();
                    phaser.arriveAndAwaitAdvance();
                }
            }
        }
    }
    public static class Abs implements Runnable{
        protected Phaser phaser;
        protected PhaserList list ;
        public Abs(Phaser phaser , PhaserList list){
            this.phaser = phaser ;
            this.list = list ;
        }
        @Override
        public void run() {

        }
    }
    public static class PrintPhase extends Phaser {
        @Override
        protected boolean onAdvance(int phase, int registeredParties) {
            switch (phase){
                case 0 :
                    return false;
                case 1 :
                    return false ;
                case 2 :
                    return false;
                default:
                    return true ;
            }
        }
    }
}
